using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace BardsTaleMapViewer {
  public class Items {
    public Game _game;

    public List<string> _itemsName;
    public List<string> _itemTypesString;
    public List<int> _itemsUnk03;
    public List<int> _itemsUnk01AndArmorClass;
    public List<int> _itemsAttackEffectAndType;
    public List<int> _itemsAllowedCategoryToEquipMask;
    public List<int> _itemsSpecialUnk02AndType;
    public List<int> _itemSpecialTypesSpellIndex;
    public List<int> _itemsWeaponDamageBonusAndArmorClassNotUsed;
    public List<int> _itemsWeaponAttackDices;
    public List<int> _itemsCostBits;

    public List<int> _classesAllowedCategoriesToEquipBits;
    public List<string> _classesString;

    public List<Item> _items;

    public Items (Game game) {
      _game = game;

      // ItemsName
      _itemsName = Game.ReadArrayString (0x2E18A, 0x2E38A, 128, false);

      // ItemTypesName
      _itemTypesString = Game.ReadArrayString (0x2E38A, 0x2E3B6, 11, false);

      // ItemsUnk03
      _itemsUnk03 = Game.ReadArrayInt (0x2E3E8, 0x2E468, 128);

      // ItemsUnk01AndArmorClass
      _itemsUnk01AndArmorClass = Game.ReadArrayInt (0x2E468, 0x2E4E8, 128);

      // ItemsTypeAndAttackEffect
      _itemsAttackEffectAndType = Game.ReadArrayInt (0x2E4E8, 0x2E568, 128);

      // ItemsAllowedCategoryToEquipMask
      _itemsAllowedCategoryToEquipMask = Game.ReadArrayInt (0x2E568, 0x2E5E8, 128);

      // ItemsSpecialUnk02AndEffectType
      _itemsSpecialUnk02AndType = Game.ReadArrayInt (0x2E5E8, 0x2E668, 128);

      // ItemSpecialTypesSpellIndex
      _itemSpecialTypesSpellIndex = Game.ReadArrayInt (0x2E668, 0x2E6A8, 64);

      // ClassesString
      _classesString = Game.ReadArrayString (0x2E3B6, 0x2E3DE, 10, false);

      // ClassesAllowedCategoriesToEquipBits
      _classesAllowedCategoriesToEquipBits = Game.ReadArrayInt (0x2E3DE, 0x2E3E8, 10);

      // ItemsWeaponDamageBonusAndAC
      _itemsWeaponDamageBonusAndArmorClassNotUsed = Game.ReadArrayInt (0x2F1D8, 0x2F258, 128);

      // ItemsWeaponAttackDices
      _itemsWeaponAttackDices = Game.ReadArrayInt (0x2F262, 0x2F2E2, 128);

      // ItemsWeaponAttackDices
      _itemsCostBits = Game.ReadArrayInt (0x31292, 0x31312, 128);

      // Items
      _items = new List<Item> ();
      for (int i = 0; i < 128; i++) {
        Item item = new Item (i, this);
        _items.Add (item);
      }

      foreach (Item item in _items)
        if (item.ArmorClass != item.WeaponArmorClassNotUsed)
          throw new Exception ();

    }

    public void Dump () {
      //Console.WriteLine (string.Format ("{0,3}  {1,1}  {2,1}  {3,-4}  {4,-15}  {5,-22}  {6,-2}  {7,-9}  {8,-2}  {9,-3}  {10,-22}  {11,4}",
      //  "#", "C", "L", "Code", "Name", "Function", "SP", "Target", "In", "Out", "Param", "Attr"));

      int typeLength = Game.Lengthest (_itemTypesString);
      int nameLength = Game.Lengthest (_itemsName);
      int nbClasses = _classesString.Count;
      int attackEffectLength = Game.Lengthest (MonsterType._attackEffectsString);

      StringBuilder sb = new StringBuilder ();
      sb.AppendFormat ("{0,3}", "#");
      sb.AppendFormat ("  {0,-8}", "AtDiff");
      sb.AppendFormat ("  {0,-" + typeLength + "}", "Type");
      sb.AppendFormat ("  {0,-" + nameLength + "}", "Name");
      sb.AppendFormat ("  {0,-6}", "Cost");
      sb.AppendFormat ("  {0,-" + nbClasses + "}", "Classes");
      sb.AppendFormat ("  {0,-13}", "Damage");
      //sb.AppendFormat ("  {0,-6}", "Damage");
      sb.AppendFormat ("  {0,-" + attackEffectLength + "}", "AttackEffect");
      sb.AppendFormat ("  {0,2}", "AC");
      //sb.AppendFormat ("  {0,5}", "Unk01");
      //sb.AppendFormat ("  {0,5}", "Unk03");
      //sb.AppendFormat ("  {0,5}", "Unk02");
      sb.AppendFormat ("  {0,-5}", "Uses");
      sb.AppendFormat ("  {0}", "Special");
      Console.WriteLine (sb.ToString ());

      foreach (Item item in _items)
        //if (spell.FunctionEnum == FunctionsEnum.RepelUndead)
        item.Dump ();
    }

    public StringBuilder DumpHtml () {
      //Console.WriteLine (string.Format ("{0,3}  {1,1}  {2,1}  {3,-4}  {4,-15}  {5,-22}  {6,-2}  {7,-9}  {8,-2}  {9,-3}  {10,-22}  {11,4}",
      //  "#", "C", "L", "Code", "Name", "Function", "SP", "Target", "In", "Out", "Param", "Attr"));

      int typeLength = Game.Lengthest (_itemTypesString);
      int nameLength = Game.Lengthest (_itemsName);
      int nbClasses = _classesString.Count;
      int attackEffectLength = Game.Lengthest (MonsterType._attackEffectsString);

      StringBuilder sb = new StringBuilder ();
      sb.AppendLineFormat ("<table>");
      sb.AppendFormat ("<tr>");
      sb.AppendFormat ("<th class='title'>{0}</th>", "#");
      sb.AppendFormat ("<th class='title'>{0}</th>", "At Difficulty");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Type");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Name");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Cost");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Classes");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Damage");
      //sb.AppendFormat ("  {0,-6}", "Damage");
      sb.AppendFormat ("<th class='title'>{0}</th>", "AttackEffect");
      sb.AppendFormat ("<th class='title'>{0}</th>", "AC");
      //sb.AppendFormat ("  {0,5}", "Unk01");
      //sb.AppendFormat ("  {0,5}", "Unk03");
      //sb.AppendFormat ("  {0,5}", "Unk02");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Uses");
      sb.AppendFormat ("<th class='title'>{0}</th>", "Special");
      sb.AppendFormat ("</tr>");
      sb.AppendLine ();

      foreach (Item item in _items)
        //if (spell.FunctionEnum == FunctionsEnum.RepelUndead)
        sb.AppendLine (item.DumpHtml ().ToString ());

      sb.AppendLineFormat ("</table>");
      return (sb);
    }
  }
}
